package cat.inkubator.plugin4j;

import cat.inkubator.plugin4j.download.DownloadManager;
import cat.inkubator.plugin4j.download.UpdateLocalXML;
import cat.inkubator.plugin4j.updater.ObtainWebInfo;
import java.io.File;
import cat.inkubator.plugin4j.xml.Configuration;
import cat.inkubator.plugin4j.xml.Xmlizer;
import cat.inkubator.plugin4j.updater.PluginUpdater;
import cat.inkubator.plugin4j.updater.UpdateManifest;
import cat.inkubator.plugin4j.xml.Plugins;
import java.util.ArrayList;

/**
 *
 * @author gato
 */
public class PluginManager {

    private Configuration configuration;
    private Plugins pluginsLocal;
    private Plugins pluginsWeb;
    private MessageFrame message;

    public PluginManager() {
        File file = new File("plugin4j.conf");

        try {
            Xmlizer xml = new Xmlizer(Configuration.class);
            configuration = (Configuration) xml.fromFileXml(file);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public PluginManager(String url, String targetFolder, File file) {
        configuration = new Configuration();

        configuration.setUrlPlugins(url);
        configuration.setTargetFolder(targetFolder);
        configuration.setFile(file);
    }

    /**
     * This method update the different modules in the program and
     * modify the proper MANIFESTs.
     * @return True if the process execution end correctly or false
     * in the other case.
     */
    public boolean update() {

        message = new MessageFrame("Checking for Updates", null);

        this.initPluginData();

        PluginUpdater pluginUpdater = new PluginUpdater();
        if (pluginUpdater.update(this.pluginsLocal, this.pluginsWeb)) {

            DownloadManager manager = new DownloadManager(pluginUpdater.getDownload(),
                    configuration.getTargetFolder());

            message.setMessage("Downloading Modules");
            manager.startDownload();

            UpdateLocalXML.updateLocalXML(this.pluginsLocal.getPlugins(),
                    this.pluginsWeb.getPlugins(), pluginUpdater.getVersionUpdate());
        }

        this.pluginsLocal.toFile("plugins.xml");

        message.dispose();

        return true;
    }

    @Deprecated
    private boolean updateSubmodulesProcess(PluginUpdater pluginUpdater) {

        //SUBMODULES
        int sizeW = pluginsWeb.getPlugins().size();
        int sizeL = pluginsLocal.getPlugins().size();
        ArrayList<Integer> manifest = new ArrayList();
        for (int i = 0; i < sizeW; i++) {

            message.setMessage("Checking Submodules");
            String plugWeb = pluginsWeb.getPlugins().get(i).getGroupId() + ":" +
                    pluginsWeb.getPlugins().get(i).getArtifactId();

            for (int j = 0; j < sizeL; j++) {

                String plugLocal = pluginsLocal.getPlugins().get(j).getGroupId() + ":" +
                        pluginsLocal.getPlugins().get(j).getArtifactId();

                if (plugWeb.equals(plugLocal)) {
                    this.updateSubmodules(pluginsLocal.getPlugins().get(j).getDependencies(),
                            pluginsWeb.getPlugins().get(i).getDependencies());

                    pluginsLocal.getPlugins().get(j).setDependencies(pluginsWeb.getPlugins().get(i).getDependencies());
                    manifest.add(j);
                }

            }

        }

        this.updateManifest(pluginUpdater.getVersionUpdate(), manifest);

        return true;
    }

    private void updateSubmodules(Plugins localDep, Plugins webDep) {

        PluginUpdater pluginUpdater = new PluginUpdater();
        if (pluginUpdater.update(localDep, webDep)) {

            DownloadManager manager = new DownloadManager(pluginUpdater.getDownload(),
                    configuration.getTargetFolder());

            message.setMessage("Downloading Submodules");
            manager.startDownload();

        }

    }

    private void updateManifest(ArrayList<int[]> modulesUpdated, ArrayList<Integer> submodulesUpdated) {

        int subSize = submodulesUpdated.size();
        int modSize = modulesUpdated.size();
        boolean reManifest = true;

        for (int i = 0; i < subSize; i++) {

            int local = submodulesUpdated.get(i);
            int[] modules = null;
            for (int j = 0; j < modSize; j++) {

                modules = modulesUpdated.get(j);
                if (local == modules[0]) {
                    reManifest = false;
                    break;
                }

            }

            UpdateManifest updateManifest = new UpdateManifest(
                    pluginsLocal.getPlugins().get(local));
            updateManifest.updateManifestFromPlugin(
                    pluginsWeb.getPlugins().get(modules[1]).getDependencies().getPlugins());

        }

    }

    private void initPluginData() {
        String webXML = ObtainWebInfo.obtainXMLFrom(configuration.getUrlPlugins());

        try {
            Xmlizer xml = new Xmlizer(Plugins.class);
            pluginsWeb = (Plugins) xml.fromXml(webXML);

            File file = new File("plugins.xml");
            pluginsLocal = (Plugins) xml.fromFileXml(file);
        } catch (Exception jaxbe) {
            jaxbe.printStackTrace();
        }
    }

    public void executeMainProgram() {

        try {
            String command = "java -jar " + configuration.getFile().getAbsolutePath();
            Runtime.getRuntime().exec(command);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
